home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / LIB / GLSMAP / smap_rvec2st.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  2.1 KB  |  80 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1998.  */
  3.  
  4. /* This program is freely distributable without licensing fees
  5.    and is provided without guarantee or warrantee expressed or
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <math.h>
  9.  
  10. #include "glsmapint.h"
  11.  
  12. /* (x,y,z) reflection vector --> (s,t) sphere map coordinates */
  13. int
  14. smapRvecToSt(float rvec[3], float st[2])
  15. {
  16.     double m, recipm;
  17.  
  18.     /* In Section 2.10.4 ("Generating texture coordinates")
  19.        of the OpenGL 1.1 specification, you will find the
  20.        GL_SPHERE_MAP equations:
  21.  
  22.           n' = normal after transformation to eye coordinates
  23.           u  = unit vector from origin to vertex in eye coordinates
  24.  
  25.           (rx, ry, rz) = u - 2 * n' * transpose(n') * u
  26.  
  27.           m  = 2 * sqrt(rx^2 + ry^2 + (rz + 1)^2))
  28.  
  29.           s = rx/m + 0.5
  30.           t = ry/m + 0.5
  31.  
  32.         The equation for calculating (rx, ry, rz) is the
  33.         equation for calculating the reflection vector for
  34.         a surface and observer.  The explanation and
  35.         derivation for this equation is found in Roger's
  36.         "Procedural Elements for Computer Graphics" 2nd ed.
  37.         in Section 5-5 ("Determining the Reflection Vector").
  38.         Note that Roger's convention has the Z axis in
  39.         the opposite direction from the OpenGL convention. */
  40.  
  41.     m = 2 * sqrt(rvec[0]*rvec[0] +
  42.                  rvec[1]*rvec[1] +
  43.                  (rvec[2]+1)*(rvec[2]+1));
  44.     if (m == 0.0) {
  45.         /* Some point on the sphere map perimeter. */
  46.         st[0] = 0.0;
  47.         st[1] = 0.5;
  48.         return 0;
  49.     }
  50.  
  51.     recipm = 1.0/m;
  52.  
  53.     st[0] = rvec[0]*recipm + 0.5;
  54.     st[1] = rvec[1]*recipm + 0.5;
  55.     return 1;
  56. }
  57.  
  58. /* (s,t) sphere map coordinate --> reflection verctor (x,y,z) */
  59. void
  60. smapStToRvec(float *st, float *rvec)
  61. {
  62.     double tmp1, tmp2;
  63.  
  64.     /* Using algebra to invert the sphere mapping equations
  65.        shown above in smapRvecToSt, you get:
  66.  
  67.          rx = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*s-1)
  68.          ry = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*t-1)
  69.          rz = -8*s^2 + 8*s - 8*t^2 + 8*t - 3
  70.  
  71.        The C code below eliminates common subexpressions. */
  72.  
  73.     tmp1 = st[0]*(1-st[0]) + st[1]*(1-st[1]);
  74.     tmp2 = 2 * sqrt(4*tmp1 - 1);
  75.  
  76.     rvec[0] = tmp2 * (2*st[0]-1);
  77.     rvec[1] = tmp2 * (2*st[1]-1);
  78.     rvec[2] = 8 * tmp1 - 3;
  79. }
  80.